package cn.dvptech.remotecontrol.screenmirror

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Intent
import android.graphics.Color
import android.media.projection.MediaProjectionManager
import android.os.Binder
import android.os.Build
import android.os.IBinder
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import cn.dvptech.remotecontrol.R
import cn.dvptech.remotecontrol.screenmirror.configuration.AudioConfiguration
import cn.dvptech.remotecontrol.screenmirror.configuration.VideoConfiguration
import cn.dvptech.remotecontrol.screenmirror.controller.NormalAudioController
import cn.dvptech.remotecontrol.screenmirror.controller.ScreenVideoController
import cn.dvptech.remotecontrol.screenmirror.controller.StreamController
import cn.dvptech.remotecontrol.screenmirror.packer.TcpPacker
import cn.dvptech.remotecontrol.screenmirror.screenHelper.Constant
import cn.dvptech.remotecontrol.screenmirror.sender.OnSenderListener
import cn.dvptech.remotecontrol.screenmirror.sender.TcpSender
import com.blankj.utilcode.util.ScreenUtils


/**
 *    author  : ulongx
 *    website : www.dvptech.cn
 *    date    : 2024/7/22
 *    desc    :
 */
class ScreenRecorderService : Service(), OnSenderListener {

    private var tcpSender: TcpSender? = null
    private var mStreamController: StreamController? = null
    private var mVideoConfiguration: VideoConfiguration? = null
    private var mAudioConfiguration: AudioConfiguration? = null

    private var channelId: String = "mirror.hsl"
    var id: String = "screen_mirror_channel"
    var name: String = "sx_mirror_service"

    private var mCurrentBps = 0
    private var netBodCount = 0

    private var mSenderListener: OnSenderListener? = null

    inner class ScreenBinder : Binder() {
        fun getService(): ScreenRecorderService {
            return this@ScreenRecorderService
        }
    }

    private val mBinder: IBinder = ScreenBinder()

    override fun onBind(p0: Intent?): IBinder {
        return mBinder
    }

    override fun onCreate() {

        initNotificationChannel()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // 在这里执行 Service的任务
        return START_STICKY // 或其他合适的返回值
    }

    fun startScreenCapture(
        mMediaProjectionManager: MediaProjectionManager,
        resultCode: Int,
        resultData: Intent,
        serverIp: String,
        listener: OnSenderListener
    ) {
        if (mStreamController == null) {
            val audioController = NormalAudioController()
            val videoController = ScreenVideoController(mMediaProjectionManager, resultCode, resultData)
            mStreamController = StreamController(videoController, audioController)
        }
        mSenderListener = listener

        val packer = TcpPacker()
        packer.setSendAudio(true)
        packer.initAudioParams(AudioConfiguration.DEFAULT_FREQUENCY, 16, false)


        //指定宽度根据设备屏幕比例设置录制宽高
        val recordWidth = 720
        val recordHeight = (recordWidth / (ScreenUtils.getScreenWidth() / ScreenUtils.getScreenHeight().toFloat())).toInt()

        mVideoConfiguration = VideoConfiguration.AdvancedBuilder().setHeight(recordHeight).setWidth(recordWidth).build()
        mAudioConfiguration = AudioConfiguration.Builder().setAec(false).setMic(false).build()
        mStreamController?.setVideoConfiguration(mVideoConfiguration)
        mStreamController?.setAudioConfiguration(mAudioConfiguration)
        mStreamController?.setPacker(packer)
//        mStreamController?.mute(true)

        tcpSender = TcpSender(serverIp, Constant.port)
        tcpSender?.setSenderListener(this)
        tcpSender?.setVideoParams(mVideoConfiguration)
        tcpSender?.openConnect()

        mStreamController?.setSender(tcpSender)
        mStreamController?.start()
    }


    fun stopRecording() {
        if (mStreamController != null) {
            mStreamController!!.stop()
        }
        shutDown()
//        stopForeground(true)
    }

    fun pauseRecording() {
        if (mStreamController != null) {
            mStreamController!!.pause()
        }
    }


    fun resumeRecording() {
        if (mStreamController != null) {
            mStreamController!!.resume()
        }
    }

    fun setRecordBps(bps: Int): Boolean {
        return if (mStreamController != null) {
            mStreamController!!.setVideoBps(bps)
        } else {
            false
        }
    }


    private fun initNotificationChannel() {
        // 8.0 以上需要特殊处理
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            channelId = createNotificationChannel()
        }

        val builder = NotificationCompat.Builder(this, channelId)
        val notification: Notification = builder.setOngoing(true)
            .setSmallIcon(R.mipmap.launcher_ic)
            .setPriority(NotificationCompat.PRIORITY_MIN)
            .setCategory(Notification.CATEGORY_SERVICE)
            .build()
        startForeground(17715, notification)
    }

    /**
     * 创建通知通道
     * @return
     */
    @RequiresApi(Build.VERSION_CODES.O)
    private fun createNotificationChannel(): String {
//        val channelId = "mirror.hsl"
        val chan = NotificationChannel(channelId, "ForegroundService", NotificationManager.IMPORTANCE_NONE)
        chan.lightColor = Color.BLUE
        chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
        val service = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        service.createNotificationChannel(chan)
        return channelId
    }

    override fun onRebind(intent: Intent?) {
        super.onRebind(intent)
    }

    override fun onUnbind(intent: Intent?): Boolean {
        stopRecording()
        return true
    }

    override fun onDestroy() {
        stopRecording()
        super.onDestroy()
    }


    /***** sender listener *****/

    override fun onConnecting() {
        mSenderListener?.onConnecting()
    }

    override fun onConnected() {
        mCurrentBps = mVideoConfiguration!!.maxBps
        mSenderListener?.onConnected()
    }

    override fun onDisConnected() {
        mSenderListener?.onDisConnected()
    }

    override fun onPublishFail() {
        mSenderListener?.onPublishFail()
    }

    override fun onNetGood() {
        //网络好
        netBodCount = 0
        if (mCurrentBps == mVideoConfiguration!!.maxBps) {
            return
        }
        val bps = if (mCurrentBps + 100 <= mVideoConfiguration!!.maxBps) {
            mCurrentBps + 100
        } else {
            mVideoConfiguration!!.maxBps
        }
        val result = mStreamController!!.setVideoBps(bps)
        if (result) {
            mCurrentBps = bps
        }
        mSenderListener?.onNetGood()
    }

    override fun onNetBad() {
        //网络差
        if (mCurrentBps == mVideoConfiguration!!.minBps) {
            netBodCount++
            if (netBodCount >= 2) {
                netBodCount = 0
            }
            return
        }
        val bps = if (mCurrentBps - 550 >= mVideoConfiguration!!.minBps) {
            mCurrentBps - 550
        } else {
            mVideoConfiguration!!.minBps
        }
        val result = mStreamController!!.setVideoBps(bps)
        if (result) {
            mCurrentBps = bps
        }
        mSenderListener?.onNetBad()
    }

    override fun onReceiveMessage(message: String?) {
        mSenderListener?.onReceiveMessage(message)
    }

    override fun shutDown() {
        mSenderListener?.shutDown()
    }

    /**
     * 发送消息
     */
    fun sendMessage(message: String) {
        tcpSender?.sendMessage(message)
    }
}